package bard.partnermatchingsystem.service.impl;


import bard.partnermatchingsystem.Common.ErrorCode;
import bard.partnermatchingsystem.contant.UserConstant;
import bard.partnermatchingsystem.domain.R.R;
import bard.partnermatchingsystem.domain.po.User;
import bard.partnermatchingsystem.domain.vo.UserVO;
import bard.partnermatchingsystem.exception.CommonException;
import bard.partnermatchingsystem.mapper.UserMapper;
import bard.partnermatchingsystem.service.UserService;
import bard.partnermatchingsystem.utils.LevenshteinDistance;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;

import static bard.partnermatchingsystem.contant.UserConstant.USER_LOGIN_STATE;

/**
 * @author Administrator
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2024-07-20 15:49:34
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    private static final String SALT = "bard";
    @Autowired
    private UserMapper userMapper;

    /**
     * 注册
     * @param userAccount
     * @param password
     * @param checkPassword
     * @param planetCode
     * @return
     */
    @Override
    public int UserRegister(String userAccount, String password, String checkPassword, String planetCode) {
        // 1、校验
        if (StringUtils.isAnyBlank(userAccount, password, checkPassword)) {
            return -1;
        }
        if (userAccount.length() < 4) {
            return -1;
        }
        if (password.length() < 8 || checkPassword.length() < 8) {
            return -1;
        }

        //校驗賬戶不包含特殊字符
        String validPattern = "^[a-zA-Z0-9]+$";
        if (!userAccount.matches(validPattern)) {
            return -1;
        }
        //判斷密碼是否相同
        if (!password.equals(checkPassword)) {
            return -1;
        }
        //查詢賬戶是否重複
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", userAccount);
        if (userMapper.selectOne(queryWrapper) != null) {
            return -1;
        }
        //加密
        String newPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        User user = User.builder()
                .userName(userAccount)
                .userAccount(userAccount)
                .userPassword(newPassword)
                .planetCode(planetCode)
                .build();
        boolean save = this.save(user);
        if (!save) {
            return -1;
        }

        return 1;
    }

    /**
     *
     * 登录
     * @param userAccount
     * @param password
     * @param request
     * @return
     */
    @Override
    public User doLogin(String userAccount, String password, HttpServletRequest request) {

        // 1、校验
        if (StringUtils.isAnyBlank(userAccount, password)) {
            return null;
        }
        if (userAccount.length() < 4) {
            return null;
        }
        if (password.length() < 8) {
            return null;
        }
        //校驗賬戶不包含特殊字符
        String validPattern = "^[a-zA-Z0-9]+$";
        if (!userAccount.matches(validPattern)) {
            return null;
        }
        //2.查询账号和密码是否正确
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", userAccount);
        queryWrapper.eq("user_password", DigestUtils.md5DigestAsHex((SALT + password).getBytes()));
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            log.info("userAccount or userPassword is error ");
            return null;
        }
        //3.创建脱敏的用户信息
        User safeUser = getSafeUser(user);

        //4.记录用户的登录状态
        request.getSession().setAttribute(USER_LOGIN_STATE, user);

        return safeUser;
    }

    /**
     *注销用户的登录状态
     * @param request
     * @return
     */
    @Override
    public Integer doLogout(HttpServletRequest request) {
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return -1;
    }

    /**
     * 根据标签查找用户
     * @param tagsList
     * @return
     */


    public List<User>getTagsUserList(List<String> tagsList) {
        if (tagsList.isEmpty()) {
            throw new CommonException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper queryWrapper = new QueryWrapper<>();
        for (String s : tagsList) {
            queryWrapper.like("tags", s);
        }
        List <User> userlist = userMapper.selectList(queryWrapper);
        //遍历用户列表将用户信息脱敏
        List<User>safeUserList = userlist.stream()
                .map(this::getSafeUser).collect(Collectors.toList());
        System.out.println(safeUserList);
        return safeUserList;
    }
    public List<User> getTagsUserListGson(List<String> tagsList) {
        if (tagsList.isEmpty()) {
            throw new CommonException(ErrorCode.PARAMS_ERROR);
        }
        //获取所有用户
        QueryWrapper queryWrapper = new QueryWrapper<>();
        List <User>userslist = userMapper.selectList(queryWrapper);

        Gson gson = new Gson();
        // 使用 Stream API 处理查询结果
        List<User> safeUserList = userslist.stream()
                .filter(user -> {
                    // 解析 tags 字段
                    String tags = user.getTags();
                    Type setType = new TypeToken<Set<String>>(){}.getType();
                    Set<String> setTags = new Gson().fromJson(tags, setType);
                    setTags= Optional.ofNullable(setTags).orElse(new HashSet<>());

                    // 检查是否包含所有标签
                    return setTags.containsAll(tagsList);
                })
                .map(this::getSafeUser)
                .collect(Collectors.toList());

        //将用户信息脱敏
        return safeUserList;
    }

    /**
     * 将敏感信息设置为空
     * @param user
     * @return
     */

    public  User getSafeUser(User user){
        //返回脱敏后的用户信息
        return User.builder()
                .userName(user.getUserName())
                .id(user.getId())
                .userName(user.getUserName())
                .userAccount(user.getUserAccount())
                .avatarUrl(user.getAvatarUrl())
                .gender(user.getGender())
                .phone(user.getPhone())
                .email(user.getEmail())
                .userStatus(user.getUserStatus())
                .createTime(user.getCreateTime())
                .userRole(user.getUserRole())
                .planetCode(user.getPlanetCode())
                .tags(user.getTags())
                .build();
    }

    @Override
    public List<UserVO> matchUsers(long num, User loginUser) {
        // 只查询需要的字段提升查找性能
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "tags");
        queryWrapper.ne("id", loginUser.getId());
        queryWrapper.isNotNull("tags");
        List<User> userList = userMapper.selectList(queryWrapper);
        if (userList.isEmpty()) {
            throw new CommonException(ErrorCode.PARAMS_ERROR, "未找到合适的用户");
        }

        // 使用 TreeMap 存储用户分数和对应的用户列表
        TreeMap<Integer, List<User>> userMap = new TreeMap<>();
        String tags = loginUser.getTags();
        Type setType = new TypeToken<List<String>>() {}.getType();
        List<String> loginUserTags = new Gson().fromJson(tags, setType);

        for (User user : userList) {
            if (user.getTags().isEmpty()) {
                continue;
            }
            List<String> userTags = new Gson().fromJson(user.getTags(), setType);
            // 计算当前用户编辑距离
            int userScore = LevenshteinDistance.minDistance(loginUserTags, userTags);

            // 将用户按分数存储到 TreeMap 中
            userMap.computeIfAbsent(userScore, k -> new ArrayList<>()).add(user);
        }

        // 收集前 num 个用户
        List<User> selectedUsers = new ArrayList<>();
        for (List<User> users : userMap.values()) {
            for (User user : users) {
                if (selectedUsers.size() < num) {
                    selectedUsers.add(user);
                } else {
                    break;
                }
            }
            if (selectedUsers.size() >= num) {
                break;
            }
        }
        // 收集selectedUsers中的用户id
        // 收集用户ID
        List<Long> userIds = selectedUsers.stream()
                .map(User::getId) // 提取用户ID
                .toList(); // 收集到List<Long>中
        // 根据ID列表查询用户
        if (userIds.isEmpty()) {
            throw new CommonException(ErrorCode.SYSTEM_ERROR,"未找到合适的用户");
            // `users` 列表现在包含了所有对应ID的用户
        }
        List<User> users = userMapper.selectBatchIds(userIds);
        return users.stream()
                .map(user -> {
                    UserVO userVO = new UserVO();
                    BeanUtils.copyProperties(user, userVO); // 将 User 的属性复制到 UserVO
                    return userVO;
                })
                .collect(Collectors.toList()); // 收集到 List<UserVO> 中
    }



    @Override
    public User getLoginUser(HttpServletRequest request) {
        if (request == null){
            throw new CommonException(ErrorCode.NOT_LOGIN);
        }
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        return (User) userObj;
    }

    @Override
    public boolean isAdmin(User loginUser) {
        return loginUser!=null&&loginUser.getUserRole() == UserConstant.ADMIN_ROLE;
    }

    @Override
    public boolean isAdmin(HttpServletRequest request) {
        User loginUser =getLoginUser(request);
        return loginUser != null && loginUser.getUserRole()== UserConstant.ADMIN_ROLE;
    }

    @Override
    public int updateUser(User user, User loginUser) {
        Long userId=user.getId();
        if (userId<=0){
            throw new CommonException(ErrorCode.PARAMS_ERROR);
        }
        //管理员用户修改其他用户信息
        if(!isAdmin(loginUser)&&userId.equals(loginUser.getId())){
            throw new CommonException(ErrorCode.FORBIDDEN);
        }
        User oldUser=userMapper.selectById(userId);
        if (oldUser==null){
            throw new CommonException(ErrorCode.FORBIDDEN);
        }
        return userMapper.updateById(user);
    }
}





